package com.demo.service;

/**
 * @BelongsProject: demo1
 * @BelongsPackage: com.demo.service
 * @Author: fwx
 * @CreateTime: 2023-03-01  14:16
 * @Description: TODO
 * @Version: 1.0
 */

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.demo.mapper.AccountMapper;
import com.demo.mapper.DetailMapper;
import com.demo.pojo.Account;
import com.demo.pojo.Detail;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class AccountService {



    @Resource
    private AccountMapper accountMapper;
    @Resource
    private DetailMapper detailMapper;

    /**
     * @description: 消费接口(悲观锁)
     * @author: fwx
     * @date: 2023/3/1 15:52
     * @param: [accountNumber:账户号, cash:消费金额]
     * @return: void
     **/
    @Transactional
    public void expenseAccount(String accountNumber,Double cash) throws Exception {
        if(cash<=0){
            throw new Exception("消费金额应大于0");
        }


        //查询该账户余额
        LambdaQueryWrapper<Account> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Account::getAccountNumber,accountNumber);
        Account account = accountMapper.selectOne(wrapper);

        if (new BigDecimal(cash).compareTo(account.getBalance()) > 0){
            throw new Exception("余额不足");
        }

        BigDecimal newBalance=account.getBalance().subtract(new BigDecimal(cash));
        LambdaUpdateWrapper<Account> updateWrapper= new LambdaUpdateWrapper<Account>()
                .set(Account::getBalance,newBalance)
                .eq(Account::getAccountNumber,accountNumber);
        //更新账户余额
        int update = accountMapper.update(null, updateWrapper);
        //添加明细数据
        int insert = detailMapper.insert(new Detail() {{
            setAccountNumber(accountNumber);
            setBalance(newBalance);
            setDetailCash("-" + new BigDecimal(cash));
        }});

        if (update<=0&&insert<=0){
            throw new Exception("消费失败");
        }
    }

    /**
     * @description: 退回金额接口(乐观锁)
     * @author: fwx
     * @date: 2023/3/1 15:51
     * @param: [accountNumber:账户号, cash:退还金额]
     * @return: void
     **/
    @Transactional
    public void refundAccount(String accountNumber,Double cash) throws Exception {
        if(cash<=0){
            throw new Exception("退回金额应大于0");
        }

        //查询该账户余额
        LambdaQueryWrapper<Account> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Account::getAccountNumber,accountNumber);
        Account account = accountMapper.selectOne(wrapper);

        BigDecimal newBalance=account.getBalance().add(new BigDecimal(cash));
        int newVersion=account.getVersion()+1;

        LambdaUpdateWrapper<Account> updateWrapper= new LambdaUpdateWrapper<Account>()
                .set(Account::getBalance,newBalance)
                .set(Account::getVersion,newVersion)
                .eq(Account::getAccountNumber,accountNumber)
                .eq(Account::getVersion,account.getVersion());

        //更新账户余额
        int update = accountMapper.update(null, updateWrapper);
        //添加明细数据
        int insert = detailMapper.insert(new Detail() {{
            setAccountNumber(accountNumber);
            setBalance(newBalance);
            setDetailCash("-" + new BigDecimal(cash));
        }});

        if (update<=0&&insert<=0){
            throw new Exception("退回失败");
        }
    }

    /**
     * @description: 查看账户余额
     * @author: fwx
     * @date: 2023/3/1 16:02
     * @param: [accountNumber:账户号]
     * @return: void
     **/
    public void getBalance(String accountNumber){
        //查询该账户余额
        LambdaQueryWrapper<Account> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Account::getAccountNumber,accountNumber);
        Account account = accountMapper.selectOne(wrapper);

        System.out.println("账户的余额为"+account.getBalance());
    }



}
